import { CIDR_RE, IP_RE, IP_RANGE_RE } from '@util/constants';
import calcIntervalsCount from '@util/calc-intervals-count';

const getIpsFromIPRange = ipRange => {
  const ipss = ipRange.split(/\.|-/g);
  const prefix = ipss.slice(0, 3).join('.');
  let ips = [];
  for (let start = Number(ipss[3]), end = Number(ipss[4]); start <= end; start++) {
    ips.push(`${prefix}.${start}`);
  }
  return ips;
};

const getIpInNumber = ip => {
  const splices = ip.split(/\.|\//g).map(Number);
  return (splices[0] << 24) | (splices[1] << 16) | (splices[2] << 8) | splices[3];
};

const getCidrRange = cidr => {
  const splices = cidr.split(/\.|\//g).map(Number);
  const mask = Math.pow(2, 32) - Math.pow(2, 32 - splices[4]);
  const ip = (splices[0] << 24) | (splices[1] << 16) | (splices[2] << 8) | splices[3];
  const networkAddress = (ip & mask) >>> 0;
  const counts = Math.pow(2, 32 - splices[4]);
  return [networkAddress, networkAddress + counts - 1];
};

// 获取ip中不重复ip个数
const getIpsCount = ips => {
  const parsedIps = [];

  ips.forEach(ip => {
    if (CIDR_RE.test(ip)) {
      parsedIps.push(getCidrRange(ip));
    } else if (IP_RE.test(ip)) {
      parsedIps.push(getIpInNumber(ip));
    } else if (IP_RANGE_RE.test(ip)) {
      parsedIps.push(...getIpsFromIPRange(ip).map(getIpInNumber));
    }
  });

  return calcIntervalsCount(parsedIps);
};

export default getIpsCount;
